/*********************************************************************************************************
 *  ------------------------------------------------------------------------------------------------------
 *  file description
 *  ------------------------------------------------------------------------------------------------------
 *         \file  romt.h
 *         \unit  romt
 *        \brief  This is a simple rom test module for C language
 *       \author  Lamdonn
 *      \version  v0.1.0
 *      \license  GPL-2.0
 *    \copyright  Copyright (C) 2023 Lamdonn.
 ********************************************************************************************************/
#ifndef __romt_H
#define __romt_H

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

/* Version infomation */
#define ROMT_V_MAJOR                        0
#define ROMT_V_MINOR                        1
#define ROMT_V_PATCH                        0

#define ROMT_MODE_READ                      ((uint32_t)0x00000001)  ///< Mode for reading from ROM
#define ROMT_MODE_WRITE                     ((uint32_t)0x00000002)  ///< Mode for writing to ROM
#define ROMT_MODE_NORMAL                    ((uint32_t)0x00000004)  ///< Normal operation mode
#define ROMT_MODE_BOUNDARY                  ((uint32_t)0x00000008)  ///< Boundary condition mode
#define ROMT_MODE_RANDOM                    ((uint32_t)0x00000010)  ///< Random access mode
#define ROMT_MODE_PATTERN                   ((uint32_t)0x00000020)  ///< Pattern generation mode

#define ROMT_UNIT_SIZE                      ((uint16_t)256)         ///< Size of a unit data block

/**
 * \brief Type definition for read callback function.
 * \param[in] address: Address from which to read data.
 * \param[in] data: Pointer to the buffer where data will be stored.
 * \param[in] length: Number of bytes to read.
 * \return Returns the number of bytes read on success; otherwise, an error code.
 */
typedef int (*romt_read_t)(uint32_t address, uint8_t *data, uint32_t length);

/**
 * \brief Type definition for write callback function.
 * \param[in] address: Address at which to write data.
 * \param[in] data: Pointer to the buffer containing data to be written.
 * \param[in] length: Number of bytes to write.
 * \return Returns the number of bytes written on success; otherwise, an error code.
 */
typedef int (*romt_write_t)(uint32_t address, uint8_t *data, uint32_t length);

// ROM structure definition
typedef struct 
{
    uint32_t base;                          ///< Pointer to the simulated ROM
    uint32_t size;                          ///< Size of the ROM
    romt_read_t read;                       ///< Read function pointer
    romt_write_t write;                     ///< Write function pointer
    uint32_t private[4];                    ///< Private data, modification not allowed
} ROMT;

/**
 * \brief Initialize the ROMT structure.
 * 
 * This function checks the validity of the provided ROMT structure and its parameters,
 * and initializes the private data field to zero. It ensures that the size, read, and
 * write function pointers are valid before proceeding with the initialization.
 * 
 * \param[in] romt: Pointer to the ROMT structure to be initialized.
 * \return Returns 1 if initialization is successful; otherwise, returns 0.
 */
int romt_init(ROMT *romt);

/**
 * \brief Start the ROMT operations with specified mode and duration.
 * 
 * This function initializes the ROMT structure for operation by setting the test mode
 * and duration. It checks the validity of the input parameters and ensures that the ROM
 * is properly initialized before starting the operation.
 * 
 * \param[in] romt: Pointer to the ROMT structure to be started.
 * \param[in] mode: The mode of operation for the ROMT.
 * \param[in] duration: The duration for which the operation should run.
 * \return Returns 1 if the operation is successful; otherwise, returns 0.
 */
int romt_start(ROMT *romt, uint32_t mode, uint32_t duration);

/**
 * \brief Stop the ROMT operations and reset its configuration.
 * 
 * This function halts the operation of the ROMT structure and resets the test mode
 * and duration to zero. It ensures that the ROM is properly initialized before stopping
 * the operation.
 * 
 * \param[in] romt: Pointer to the ROMT structure to be stopped.
 * \return Returns 1 if the operation is successful; otherwise, returns 0.
 */
int romt_stop(ROMT *romt);

/**
 * \brief Retrieve the historical result from the ROMT structure.
 * 
 * This function checks the validity of the ROMT structure and returns the historical
 * result stored in the private data. If any checks fail, it returns 0xFFFFFFFF
 * to indicate an error.
 * 
 * \param[in] romt: Pointer to the ROMT structure from which to retrieve the result.
 * \return Returns the historical result if successful; otherwise, returns 0xFFFFFFFF.
 */
uint32_t romt_result(ROMT *romt);

/**
 * \brief Retrieve the latest result from the ROMT structure.
 * 
 * This function checks the validity of the ROMT structure and returns the latest
 * result stored in the private data. If any checks fail, it returns 0xFFFFFFFF
 * to indicate an error.
 * 
 * \param[in] romt: Pointer to the ROMT structure from which to retrieve the result.
 * \return Returns the latest result if successful; otherwise, returns 0xFFFFFFFF.
 */
uint32_t romt_result_latest(ROMT *romt);

/**
 * \brief Execute the ROMT test tasks based on the configured test mode.
 * 
 * This function checks the current test mode and performs the respective tests (read, write,
 * normal, boundary, random, pattern) on the ROMT structure if the duration allows for it.
 * It updates the latest result and accumulates the historical result in the private data.
 * 
 * \param[in] romt: Pointer to the ROMT structure to be tested.
 */
void romt_task(ROMT *romt);

#endif
